package main
import (
	"fmt"
	// "math"
)

type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M(){
	if t == nil {
		fmt.Println("<nil>")
		return 
	}
	fmt.Println(t.S)
}

type F float64

func (f F) M() {
	fmt.Println(f)
}

// func main(){
// 	//demo1
// 	// var i I
// 	// i = &T{"Hello"}
// 	// describe(i)//(&{Hello}, *main.T)
// 	// i.M()//Hello

// 	// i = F(math.Pi)
// 	// describe(i)//(3.141592653589793, main.F)
// 	// i.M()//3.141592653589793

// 	// //demo2
// 	// fmt.Println("==============demo2")
// 	// //即便接口内的具体值为nil,方法仍会被nil接收者调用
// 	// //在一些语言中，这会触发一个空指针异常，但在Go中通常会写一些方法来处理
// 	// var t *T
// 	// i = t
// 	// describe(i)//(<nil>, *main.T)
// 	// i.M()//<nil>

// 	//demo3
// 	var i I
// 	describe(i)
// 	i.M()//panic: runtime error: invalid memory address or nil pointer dereference
// }

func main(){
	var i interface{}
	describe(i)//(<nil>, <nil>)

	i = 42
	describe(i)//(42, int)

	i = "Hello"
	describe(i)//(Hello, string)
}


func describe(i interface{}){
	fmt.Printf("(%v, %T)\n",i,i)
}

// func describe(i I){
// 	fmt.Printf("(%v, %T)\n",i,i)
// }